package cacheUtil

import (
	"time"

	"github.com/go-redis/redis/v7"
	"go-api-template/api/http"
	"go-api-template/internal/e"
	"go-api-template/service"
	"golang.org/x/sync/singleflight"
)

// RequestCache 请求缓存
func RequestCache(key string, exp time.Duration, s *service.Service, sg *singleflight.Group, clean bool, doFunc func() (http.Resp, error)) (resp http.Resp, err error) {
	var data http.Resp
	err = s.Redis.Get(key).Scan(&data)

	if clean {
		service.Log.Debug("强制刷新缓存")
		goto START
	}

	// key is nil
	if err == redis.Nil {
		data = resp
	}

	// 判断数据不为空，并赋值
	if !data.IsStructureEmpty() {
		resp.SetData(data.Data)
		resp.SetCode(e.Cache)
		return
	}
START:

	// 防刺穿执行实现层
	res, err, _ := sg.Do(key, func() (interface{}, error) {
		resp, err := doFunc()
		if err != nil {
			return nil, err
		}

		// 设置缓存
		err = s.Cache.Set(key, resp, exp)
		if err != nil {
			service.Log.Sugar().Debugf("缓存失败: cacheKey=%s", key)
		} else {
			service.Log.Sugar().Debugf("缓存成功: cacheKey=%s", key)
		}
		return resp, err
	})

	// 设置返回值
	if res != nil {
		resp = res.(http.Resp)
	}
	return
}
